#include <stdio.h>
#include <sys/timeb.h>
#include <thread>
#include <atomic>
#include "threadpool.h"

const int N = 30;
const int P = 5;

std::atomic_int M0{ N };
std::atomic_int M1{ N };
std::atomic_int M2{ N };

void *
task0(void *data, int id)
{
    srand(time(NULL) + id);
    int count = rand() % 10;

    printf("count %d\n", count);
    for (int i = 0; i < count; ++i)
    {
        /* printf("thread %d\n", id); */
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    M0--;

    /* int n = M0; */
    /* printf("%d\n", n); */

    return NULL;
}

void *
task1(void *data, int id)
{
    /* printf("thread %d\n", id); */
    for (int i = 0; i < P; ++i) {}
    M1--;

    return NULL;
}

void *
task2(void *data)
{
    /* printf("thread %ld\n", (unsigned long)data); */
    for (int i = 0; i < P; ++i) {}
    M2--;

    return NULL;
}

ThreadPool *tpool = NULL;
int main(int argc, char *argv[])
{
    timeb s, e;

    ftime(&s);
    tpool = new ThreadPool(50);
    ftime(&e);
    printf("create cost: %ld\n", e.time * 1000 + e.millitm - s.time * 1000 - s.millitm);

    /* getchar(); */

    /* threadpool */
    ftime(&s);
    for (int i = 0; i < N; ++i)
    {
        while (tpool->launch(task0, NULL, i) < 0)
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(1));
        }
    }

    /* getchar(); */
    /* for (int i = 0; i < N; ++i) */
    /* { */
    /*     while (tpool->launch(task0, NULL, i) < 0) */
    /*     { */
    /*         std::this_thread::sleep_for(std::chrono::milliseconds(1)); */
    /*     } */
    /* } */

    /* while (M0 > 0) */
    /* { */
    /*     std::this_thread::sleep_for(std::chrono::milliseconds(1)); */
    /* } */
    ftime(&e);
    printf("launch cost: %ld\n", e.time * 1000 + e.millitm - s.time * 1000 - s.millitm);

#if 0
    /* std::thread */
    ftime(&s);
    for (int i = 0; i < N; ++i)
    {
        std::thread *t = new std::thread(task1, (void *)NULL, i);
        t->detach();
    }

    while (M1 > 0)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
    }

    ftime(&e);
    printf("std::thread cost: %ld\n", e.time * 1000 + e.millitm - s.time * 1000 - s.millitm);

#if 0
    /* pthread */
    pthread_t t[N];
    ftime(&s);
    for (unsigned long i = 0; i < N; ++i)
    {
        while (0 != pthread_create(&t[i], NULL, task2, (void *)i))
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(1));
        }

        pthread_detach(t[i]);
    }

    while (M2 > 0)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
    }

    ftime(&e);
    printf("pthread cost: %ld\n", e.time * 1000 + e.millitm - s.time * 1000 - s.millitm);
#endif
#endif

    getchar();

    if (tpool)
    {
        delete tpool;
    }

    getchar();

    return 0;
}
